package cn.wowjoy.office.baselivedata.appbase;


import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;

import java.lang.reflect.Field;
import java.util.List;

import javax.inject.Inject;

import cn.wowjoy.office.R;
import cn.wowjoy.office.common.widget.MyToast;
import cn.wowjoy.office.data.constant.Constants;
import cn.wowjoy.office.data.remote.ApiException;
import cn.wowjoy.office.data.remote.ERROR;
import cn.wowjoy.office.data.remote.ExceptionEgine;
import cn.wowjoy.office.databinding.ErrorViewBinding;
import cn.wowjoy.office.loginnew.LoginActivity;
import cn.wowjoy.office.utils.PreferenceManager;
import dagger.android.support.DaggerFragment;

/**
 * Created by Sherily on 2017/12/18.
 * Description:
 */

public abstract class NewBaseFragment<DB extends ViewDataBinding, VM extends NewBaseViewModel> extends DaggerFragment {

    @Inject
    ViewModelProvider.Factory viewModelFactory;
    @Inject
    public PreferenceManager preferenceManager;

    private boolean isInit = false;
    private boolean isStart = false;
    private Bundle savedInstanceState;
    public static final String INTENT_BOOLEAN_LAZYLOAD = "intent_boolean_lazyLoad";
    private boolean isLazyLoad = true;
    private ErrorViewBinding errorViewBinding;
    private View mRoot;

    private int isVisibleToUserState = VISIBLE_STATE_NOTSET;
    //未设置值
    private static final int VISIBLE_STATE_NOTSET = -1;
    //可见
    private static final int VISIBLE_STATE_VISIABLE = 1;
    //不可见
    private static final int VISIBLE_STATE_GONE = 0;


    private IntentFilter intentFilter;
    private ScanReceiver scanReceiver;
    protected VM viewModel;

    protected DB binding;



    protected abstract Class<VM> getViewModel();

    @LayoutRes
    protected abstract int getLayoutId();


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    //    RxBus.getInstance().register(this);
        viewModel = ViewModelProviders.of(this, viewModelFactory).get(getViewModel());
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        this.savedInstanceState = savedInstanceState;
        binding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false);
        mRoot = binding.getRoot();
        Bundle bundle = getArguments();
        initBroadCast();
        if (bundle != null) {
            isLazyLoad = bundle.getBoolean(INTENT_BOOLEAN_LAZYLOAD, isLazyLoad);
        }

        //直接在每个子presenter通过dagger注入的方式进行自动关联viewmodel,activity。
        //为什么不直接getUserVisibleHint();而是通过自己存isVisibleToUserState变量判断
        //因为v4的25的版本 已经调用 setUserVisibleHint(true)，结果到这里getUserVisibleHint是false
        // （ps:看了FragmentManager源码Fragment被重新创建有直接赋值isVisibleToUser不知道是不是那里和之前v4有改动的地方）
        //所以我默认VISIBLE_STATE_NOTSET，之前没有调用setUserVisibleHint方法，就用系统的getUserVisibleHint，否则就用setUserVisibleHint后保存的值
        //总之就是调用了setUserVisibleHint 就使用setUserVisibleHint的值
        boolean isVisibleToUser;
        if (isVisibleToUserState == VISIBLE_STATE_NOTSET) {
            isVisibleToUser = getUserVisibleHint();
        } else {
            isVisibleToUser = isVisibleToUserState == VISIBLE_STATE_VISIABLE;
        }

        if (isLazyLoad) {
            if (isVisibleToUser) {
                isInit = true;
                onCreateViewLazy(savedInstanceState);
            }
        } else {
            isInit = true;
            onCreateViewLazy(savedInstanceState);
        }

        if(null == binding.getRoot())
            return super.onCreateView(inflater, container, savedInstanceState);
        return binding.getRoot();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isVisibleToUserState = isVisibleToUser ? VISIBLE_STATE_VISIABLE : VISIBLE_STATE_GONE;
        if (isVisibleToUser && !isInit && mRoot != null) {
            isInit = true;
            onCreateViewLazy(savedInstanceState);
            onResumeLazy();
        }
        if (isInit && mRoot != null) {
            if (isVisibleToUser) {
                isStart = true;
                onStartLazy();
            } else {
                isStart = false;
                onStopLazy();
            }
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
    @Deprecated
    @Override
    public final void onStart() {
        super.onStart();
        if (isInit && !isStart && getUserVisibleHint()) {
            isStart = true;
            onStartLazy();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (isInit && isStart && getUserVisibleHint()) {
            isStart = false;
            onStopLazy();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (isInit) {
            onResumeLazy();
        }
    }

    @Override
    @Deprecated
    public final void onPause() {
        super.onPause();
        if (isInit) {
            onPauseLazy();
        }
    }

    @Override
    @Deprecated
    public final void onDestroyView() {
        super.onDestroyView();
        mRoot = null;
        binding.unbind();
        viewModel.onDestroy();

        if (isInit) {
            onDestroyViewLazy();
        }
        isInit = false;
     //   RxBus.getInstance().unRegister(this);
    }

    protected void onResumeLazy(){}

    protected void onStartLazy(){}

    protected void onStopLazy(){}

    protected void onPauseLazy(){}

    protected void onDestroyViewLazy(){}

    protected abstract void onCreateViewLazy(Bundle savedInstanceState);

    protected void hideSoftInput(){
        InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(binding.getRoot().getWindowToken(), 0);
    }




    /**
     * baseActivity中handleException(Exception e,boolean needErrorView):
     *统一处理exception，当needErrorView = true,是，需要在getErrorview中返回承载errorview的布局，
     *目前支持Framelayout，可以覆盖后面的结果页面。当needErrorView = false,用toast的形式提醒错误，401的状态下统一跳转至LoginActivity
     * @param e
     * @param needErrorview
     */
    public void handleException(Throwable e,boolean needErrorview){
        ApiException apiException = ExceptionEgine.handleException(e);
        if (apiException.getCode() == ERROR.UNAUTHORIZED){
            new MyToast(getContext()).showinfo(apiException.getMessage());
            preferenceManager.clearToken();
            LoginActivity.startAndClearTask(getActivity());

        } else {
            if (needErrorview){
                createErrorView(apiException);
            } else {
                new MyToast(getContext()).showinfo(apiException.getMessage());
            }

        }
    }
    public void handleExceptionPM(Throwable e,boolean needErrorview){
        ApiException apiException = ExceptionEgine.handleException(e);
        if (apiException.getCode() == ERROR.UNAUTHORIZED){
            new MyToast(getContext()).showinfo(apiException.getMessage());
            preferenceManager.clearToken();
            LoginActivity.startAndClearTask(getActivity());
        }else if(apiException.getCode() == ERROR.NETWORD_ERROR_PM){
            if (null != getErrorViewRoot()){
                if (null != errorViewBinding){
                    removeErrorview();
                }
                hideSoftInput();
                LayoutInflater  inflater =  LayoutInflater.from(getErrorViewRoot().getContext());
                errorViewBinding = DataBindingUtil.inflate(inflater, R.layout.error_view,getErrorViewRoot(),false);
                errorViewBinding.getRoot().setClickable(true);
                errorViewBinding.errorContent.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.no_wifi,0,0);
                errorViewBinding.errorContent.setText("网络不在状态，您可以直接扫码离线生成PM报告");
                errorViewBinding.errorContent.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        refreshError();
                    }
                });
                ViewGroup.LayoutParams layoutParams = getErrorViewRoot().getLayoutParams();
                getErrorViewRoot().addView(errorViewBinding.getRoot(),layoutParams);
            } else {
                //知道你们会忘记加布局，为了防止异常，有toast提醒
                new MyToast(getContext()).showinfo(e.getMessage());
            }
        } else {
            if (needErrorview){
                createErrorView(apiException);
            } else {
                new MyToast(getContext()).showinfo(e.getMessage());
            }

        }
    }

    /**
     * 在每个子activity中实现，哪一块区域需要用，就返回哪块，目前只考虑FrameLayout
     * @return
     */
    protected ViewGroup getErrorViewRoot(){

        return  null;
    }

    /**
     * 记住，记住，记住，在需要errorview通过 getErrorViewRoot()返回承载errorview的布局，目前支持Framelayout
     * @param e
     */
    private void createErrorView( ApiException e){
        if (null != getErrorViewRoot()){
            if (null != errorViewBinding){
                removeErrorview();
            }
            hideSoftInput();
            LayoutInflater  inflater =  LayoutInflater.from(getErrorViewRoot().getContext());
            errorViewBinding = DataBindingUtil.inflate(inflater, R.layout.error_view,getErrorViewRoot(),false);
            errorViewBinding.getRoot().setClickable(true);
            switch (e.getCode()){
                case 404:
                    errorViewBinding.errorContent.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.error_404,0,0);
                    errorViewBinding.errorContent.setText(e.getMessage());
                    break;
                case 500:
                    errorViewBinding.errorContent.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.error_500,0,0);
                    errorViewBinding.errorContent.setText(e.getMessage());
                    break;
                case 1002:
                    errorViewBinding.errorContent.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.wi_fi,0,0);
                    errorViewBinding.errorContent.setText(e.getMessage());
                    break;
                case 1005:
                    errorViewBinding.errorContent.setCompoundDrawablesWithIntrinsicBounds(0,R.mipmap.no_wifi,0,0);
                    errorViewBinding.errorContent.setText(e.getMessage());
                    break;
                default:
                    errorViewBinding.errorContent.setText(e.getMessage());
                    break;
            }
            errorViewBinding.errorContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    refreshError();
                }
            });
            ViewGroup.LayoutParams layoutParams = getErrorViewRoot().getLayoutParams();
            getErrorViewRoot().addView(errorViewBinding.getRoot(),layoutParams);
        } else {
            //知道你们会忘记加布局，为了防止异常，有toast提醒
            new MyToast(getContext()).showinfo(e.getMessage());
        }


    }


    /**
     *在refreshError之后记住removeErroeView
     */
    protected void removeErrorview(){

        if (null != getErrorViewRoot()){
            getErrorViewRoot().removeView(errorViewBinding.getRoot());
        }
    }

    /**
     * errorView添加后，点击error图片即可重新请求相应的接口，进行处理
     */
    protected void refreshError(){
        removeErrorview();
        //具体页面实现请求对应接口渲染数据
    }
    /**
     * 初始化广播
     */
    private void initBroadCast(){
        intentFilter = new IntentFilter();
        intentFilter.addAction(Constants.BAR_ADD);
        intentFilter.addAction(Constants.RFID_ADD);
        intentFilter.addAction(Constants.WOW_ADD);
        intentFilter.addAction(Constants.WOW_NEW_ADD);
        scanReceiver = new ScanReceiver();
    }


    /***
     * 扫码逻辑模块：包括注册广播，撤销广播，及扫码实现逻辑
     */

    class ScanReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Constants.BAR_ADD)) {
                new MyToast(context).showinfo(intent.getStringExtra(Constants.BAR_KEY));
                if (!"ERROR".equals(intent.getStringExtra(Constants.BAR_KEY))) {
                }
            } else if (intent.getAction().equals(Constants.RFID_ADD)) {
                new MyToast(context).showinfo(intent.getStringExtra(Constants.RFID_KEY));
                if (!"ERROR".equals(intent.getStringExtra(Constants.BAR_KEY))) {
                }
            } else if (intent.getAction().equals(Constants.WOW_ADD)) {
//                new MyToast(context).showinfo(intent.getStringExtra(Contants.WOW_KEY));
            } else if (intent.getAction().equals(Constants.WOW_NEW_ADD)) {
                String msg = intent.getStringExtra(Constants.WOW_NEW_KEY);
                brodcast(context, msg);
            }
        }
    }

    /**
     * 每个页面需要广播时候开启注册广播
     */
    protected void openBroadCast(){
        getActivity().registerReceiver(scanReceiver, intentFilter);
    }


    /**
     * 关闭广播
     */
    protected void closeBroadCast(){
        Intent intent = new Intent();
        intent.setAction(Constants.WOW_NEW_ADD);
        PackageManager pm = getActivity().getPackageManager();
        List<ResolveInfo> resolveInfos = pm.queryBroadcastReceivers(intent, 0);
        if(resolveInfos != null && !resolveInfos.isEmpty()){
            //查询到相应的BroadcastReceiver
            getActivity().unregisterReceiver(scanReceiver);
        }

    }

    /**
     * 扫码自定义逻辑实现入口
     * @param context
     * @param msg
     */
    protected void brodcast(Context context, String msg){
    }


}
